home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Utilities / BasiliskII / src / rsrc_patches.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-02  |  21.4 KB  |  631 lines

  1. /*
  2.  *  rsrc_patches.cpp - Resource patches
  3.  *
  4.  *  Basilisk II (C) 1997-2001 Christian Bauer
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  */
  20.  
  21. #include <string.h>
  22.  
  23. #include "sysdeps.h"
  24. #include "cpu_emulation.h"
  25. #include "macos_util.h"
  26. #include "main.h"
  27. #include "emul_op.h"
  28. #include "audio.h"
  29. #include "audio_defs.h"
  30. #include "rsrc_patches.h"
  31.  
  32. #if ENABLE_MON
  33. #include "mon.h"
  34. #endif
  35.  
  36. #define DEBUG 0
  37. #include "debug.h"
  38.  
  39.  
  40. #if !EMULATED_68K
  41. // Assembly functions
  42. extern "C" void Scod060Patch1(void);
  43. extern "C" void Scod060Patch2(void);
  44. extern "C" void ThInitFPUPatch(void);
  45. #endif
  46.  
  47.  
  48. /*
  49.  *  Search resource for byte string, return offset (or 0)
  50.  */
  51.  
  52. static uint32 find_rsrc_data(const uint8 *rsrc, uint32 max, const uint8 *search, uint32 search_len, uint32 ofs = 0)
  53. {
  54.     while (ofs < max - search_len) {
  55.         if (!memcmp(rsrc + ofs, search, search_len))
  56.             return ofs;
  57.         ofs++;
  58.     }
  59.     return 0;
  60. }
  61.  
  62.  
  63. /*
  64.  *  Resource patches via vCheckLoad
  65.  */
  66.  
  67. void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
  68. {
  69.     uint16 *p16;
  70.     uint32 base;
  71.     D(bug("vCheckLoad %c%c%c%c (%08x) ID %d, data %08x, size %d\n", (char)(type >> 24), (char)((type >> 16) & 0xff), (char )((type >> 8) & 0xff), (char )(type & 0xff), type, id, p, size));
  72.     
  73.     if (type == FOURCC('b','o','o','t') && id == 3) {
  74.         D(bug(" boot 3 found\n"));
  75.  
  76.         // Set boot stack pointer (7.5, 7.6, 7.6.1, 8.0)
  77.         static const uint8 dat[] = {0x22, 0x00, 0xe4, 0x89, 0x90, 0x81, 0x22, 0x40};
  78.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  79.         if (base) {
  80.             p16 = (uint16 *)(p + base + 6);
  81.             *p16 = htons(M68K_EMUL_OP_FIX_BOOTSTACK);
  82.             FlushCodeCache(p + base + 6, 2);
  83.             D(bug("  patch 1 applied\n"));
  84.         }
  85.  
  86. #if !ROM_IS_WRITE_PROTECTED
  87.         // Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.5, 8.0)
  88.         static const uint8 dat2[] = {0x20, 0x78, 0x02, 0xae, 0xd1, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x21, 0xc8, 0x00, 0x00};
  89.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  90.         if (base) {
  91.             p16 = (uint16 *)(p + base);
  92.  
  93. #if defined(AMIGA) || defined(__NetBSD__) || defined(USE_SCRATCHMEM_SUBTERFUGE)
  94.             // Set 0x0000 to scratch memory area
  95.             extern uint8 *ScratchMem;
  96.             const uint32 ScratchMemBase = Host2MacAddr(ScratchMem);
  97.             *p16++ = htons(0x207c);            // move.l    #ScratchMem,a0
  98.             *p16++ = htons(ScratchMemBase >> 16);
  99.             *p16++ = htons(ScratchMemBase);
  100.             *p16++ = htons(M68K_NOP);
  101.             *p16 = htons(M68K_NOP);
  102. #else
  103. #error System specific handling for writable ROM is required here
  104. #endif
  105.             FlushCodeCache(p + base, 14);
  106.             D(bug("  patch 2 applied\n"));
  107.         }
  108.  
  109.     } else if (type == FOURCC('b','o','o','t') && id == 2) {
  110.         D(bug(" boot 2 found\n"));
  111.  
  112.         // Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.5, 8.0)
  113.         static const uint8 dat[] = {0x20, 0x78, 0x02, 0xae, 0xd1, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x21, 0xc8, 0x00, 0x00};
  114.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  115.         if (base) {
  116.             p16 = (uint16 *)(p + base);
  117.  
  118. #if defined(AMIGA) || defined(__NetBSD__) || defined(USE_SCRATCHMEM_SUBTERFUGE)
  119.             // Set 0x0000 to scratch memory area
  120.             extern uint8 *ScratchMem;
  121.             const uint32 ScratchMemBase = Host2MacAddr(ScratchMem);
  122.             *p16++ = htons(0x207c);            // move.l    #ScratchMem,a0
  123.             *p16++ = htons(ScratchMemBase >> 16);
  124.             *p16++ = htons(ScratchMemBase);
  125.             *p16++ = htons(M68K_NOP);
  126.             *p16 = htons(M68K_NOP);
  127. #else
  128. #error System specific handling for writable ROM is required here
  129. #endif
  130.             FlushCodeCache(p + base, 14);
  131.             D(bug("  patch 1 applied\n"));
  132.         }
  133. #endif
  134.  
  135.     } else if (type == FOURCC('P','T','C','H') && id == 630) {
  136.         D(bug("PTCH 630 found\n"));
  137.  
  138.         // Don't replace Time Manager (Classic ROM, 6.0.3)
  139.         static const uint8 dat[] = {0x30, 0x3c, 0x00, 0x58, 0xa2, 0x47};
  140.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  141.         if (base) {
  142.             p16 = (uint16 *)(p + base);
  143.             p16[2] = htons(M68K_NOP);
  144.             p16[7] = htons(M68K_NOP);
  145.             p16[12] = htons(M68K_NOP);
  146.             FlushCodeCache(p + base, 26);
  147.             D(bug("  patch 1 applied\n"));
  148.         }
  149.  
  150.         // Don't replace Time Manager (Classic ROM, 6.0.8)
  151.         static const uint8 dat2[] = {0x70, 0x58, 0xa2, 0x47};
  152.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  153.         if (base) {
  154.             p16 = (uint16 *)(p + base);
  155.             p16[1] = htons(M68K_NOP);
  156.             p16[5] = htons(M68K_NOP);
  157.             p16[9] = htons(M68K_NOP);
  158.             FlushCodeCache(p + base, 20);
  159.             D(bug("  patch 1 applied\n"));
  160.         }
  161.  
  162.     } else if (type == FOURCC('p','t','c','h') && id == 26) {
  163.         D(bug(" ptch 26 found\n"));
  164.  
  165.         // Trap ABC4 is initialized with absolute ROM address (7.5, 7.6, 7.6.1, 8.0)
  166.         static const uint8 dat[] = {0x40, 0x83, 0x36, 0x10};
  167.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  168.         if (base) {
  169.             p16 = (uint16 *)(p + base);
  170.             *p16++ = htons((ROMBaseMac + 0x33610) >> 16);
  171.             *p16 = htons((ROMBaseMac + 0x33610) & 0xffff);
  172.             FlushCodeCache(p + base, 4);
  173.             D(bug("  patch 1 applied\n"));
  174.         }
  175.  
  176.     } else if (type == FOURCC('p','t','c','h') && id == 34) {
  177.         D(bug(" ptch 34 found\n"));
  178.  
  179.         // Don't wait for VIA (Classic ROM, 6.0.8)
  180.         static const uint8 dat[] = {0x22, 0x78, 0x01, 0xd4, 0x10, 0x11, 0x02, 0x00, 0x00, 0x30};
  181.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  182.         if (base) {
  183.             p16 = (uint16 *)(p + base + 14);
  184.             *p16 = htons(M68K_NOP);
  185.             FlushCodeCache(p + base + 14, 2);
  186.             D(bug("  patch 1 applied\n"));
  187.         }
  188.  
  189.         // Don't replace ADBOp() (Classic ROM, 6.0.8)
  190.         static const uint8 dat2[] = {0x21, 0xc0, 0x05, 0xf0};
  191.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  192.         if (base) {
  193.             p16 = (uint16 *)(p + base);
  194.             *p16++ = htons(M68K_NOP);
  195.             *p16 = htons(M68K_NOP);
  196.             FlushCodeCache(p + base, 4);
  197.             D(bug("  patch 2 applied\n"));
  198.         }
  199.  
  200. #if !EMULATED_68K
  201.     } else if (CPUIs68060 && (type == FOURCC('g','p','c','h') && id == 669 || type == FOURCC('l','p','c','h') && id == 63)) {
  202.         D(bug(" gpch 669/lpch 63 found\n"));
  203.  
  204.         static uint16 ThPatchSpace[1024];    // Replacement routines are constructed here
  205.         uint16 *q = ThPatchSpace;
  206.         uint32 start;
  207.         int i;
  208.  
  209.         // Patch Thread Manager thread switcher for 68060 FPU (7.5, 8.0)
  210.         static const uint8 dat[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x18};
  211.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  212.         if (base) {    // Skip first routine (no FPU -> no FPU)
  213.  
  214.             base = find_rsrc_data(p, size - base - 2, dat, sizeof(dat), base + 2);
  215.             if (base) {    // no FPU -> FPU
  216.  
  217.                 p16 = (uint16 *)(p + base);
  218.                 start = (uint32)q;
  219.                 for (i=0; i<28; i++) *q++ = *p16++;
  220.                 *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state or "FPU state saved" flag set?)
  221.                 *q++ = htons(2);
  222.                 *q++ = htons(0x6712);        // beq
  223.                 *q++ = htons(0x588f);        // addq.l #2,sp                (flag set, skip it)
  224.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpcr        (restore FPU registers)
  225.                 *q++ = htons(0x9000);
  226.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpsr
  227.                 *q++ = htons(0x8800);
  228.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpiar
  229.                 *q++ = htons(0x8400);
  230.                 *q++ = htons(0xf21f);        // fmovem.x (sp)+,fp0-fp7
  231.                 *q++ = htons(0xd0ff);
  232.                 *q++ = htons(0xf35f);        // frestore (sp)+
  233.                 *q++ = htons(0x4e75);        // rts
  234.  
  235.                 p16 = (uint16 *)(p + base);
  236.                 *p16++ = htons(M68K_JMP);
  237.                 *p16++ = htons(start >> 16);
  238.                 *p16 = htons(start & 0xffff);
  239.                 FlushCodeCache(p + base, 6);
  240.                 D(bug("  patch 1 applied\n"));
  241.  
  242.                 static const uint8 dat2[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x28};
  243.                 base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  244.                 if (base) {    // FPU -> FPU
  245.  
  246.                     p16 = (uint16 *)(p + base);
  247.                     start = (uint32)q;
  248.                     for (i=0; i<4; i++) *q++ = *p16++;
  249.                     *q++ = htons(0x6736);        // beq
  250.                     *q++ = htons(0xf327);        // fsave -(sp)                (save FPU state frame)
  251.                     *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state?)
  252.                     *q++ = htons(2);
  253.                     *q++ = htons(0x6716);        // beq
  254.                     *q++ = htons(0xf227);        // fmovem.x fp0-fp7,-(sp)    (no, save FPU registers)
  255.                     *q++ = htons(0xe0ff);
  256.                     *q++ = htons(0xf227);        // fmove.l fpiar,-(sp)
  257.                     *q++ = htons(0xa400);
  258.                     *q++ = htons(0xf227);        // fmove.l fpsr,-(sp)
  259.                     *q++ = htons(0xa800);
  260.                     *q++ = htons(0xf227);        // fmove.l fpcr,-(sp)
  261.                     *q++ = htons(0xb000);
  262.                     *q++ = htons(0x4879);        // pea -1                    (push "FPU state saved" flag)
  263.                     *q++ = htons(0xffff);
  264.                     *q++ = htons(0xffff);
  265.                     p16 += 9;
  266.                     for (i=0; i<23; i++) *q++ = *p16++;
  267.                     *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state or "FPU state saved" flag set?)
  268.                     *q++ = htons(2);
  269.                     *q++ = htons(0x6712);        // beq
  270.                     *q++ = htons(0x588f);        // addq.l #2,sp                (flag set, skip it)
  271.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpcr        (restore FPU registers)
  272.                     *q++ = htons(0x9000);
  273.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpsr
  274.                     *q++ = htons(0x8800);
  275.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpiar
  276.                     *q++ = htons(0x8400);
  277.                     *q++ = htons(0xf21f);        // fmovem.x (sp)+,fp0-fp7
  278.                     *q++ = htons(0xd0ff);
  279.                     *q++ = htons(0xf35f);        // frestore (sp)+
  280.                     *q++ = htons(0x4e75);        // rts
  281.  
  282.                     p16 = (uint16 *)(p + base);
  283.                     *p16++ = htons(M68K_JMP);
  284.                     *p16++ = htons(start >> 16);
  285.                     *p16 = htons(start & 0xffff);
  286.                     FlushCodeCache(p + base, 6);
  287.                     D(bug("  patch 2 applied\n"));
  288.  
  289.                     base = find_rsrc_data(p, size - base - 2, dat2, sizeof(dat2), base + 2);
  290.                     if (base) {    // FPU -> no FPU
  291.     
  292.                         p16 = (uint16 *)(p + base);
  293.                         start = (uint32)q;
  294.                         for (i=0; i<4; i++) *q++ = *p16++;
  295.                         *q++ = htons(0x6736);        // beq
  296.                         *q++ = htons(0xf327);        // fsave -(sp)                (save FPU state frame)
  297.                         *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state?)
  298.                         *q++ = htons(2);
  299.                         *q++ = htons(0x6716);        // beq
  300.                         *q++ = htons(0xf227);        // fmovem.x fp0-fp7,-(sp)    (no, save FPU registers)
  301.                         *q++ = htons(0xe0ff);
  302.                         *q++ = htons(0xf227);        // fmove.l fpiar,-(sp)
  303.                         *q++ = htons(0xa400);
  304.                         *q++ = htons(0xf227);        // fmove.l fpsr,-(sp)
  305.                         *q++ = htons(0xa800);
  306.                         *q++ = htons(0xf227);        // fmove.l fpcr,-(sp)
  307.                         *q++ = htons(0xb000);
  308.                         *q++ = htons(0x4879);        // pea -1                    (push "FPU state saved" flag)
  309.                         *q++ = htons(0xffff);
  310.                         *q++ = htons(0xffff);
  311.                         p16 += 9;
  312.                         for (i=0; i<24; i++) *q++ = *p16++;
  313.  
  314.                         p16 = (uint16 *)(p + base);
  315.                         *p16++ = htons(M68K_JMP);
  316.                         *p16++ = htons(start >> 16);
  317.                         *p16 = htons(start & 0xffff);
  318.                         FlushCodeCache(p + base, 6);
  319.                         D(bug("  patch 3 applied\n"));
  320.                     }
  321.                 }
  322.             }
  323.         }
  324.  
  325.         // Patch Thread Manager thread switcher for 68060 FPU (additional routines under 8.0 for Mixed Mode Manager)
  326.         static const uint8 dat3[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x40};
  327.         base = find_rsrc_data(p, size, dat3, sizeof(dat3));
  328.         if (base) {    // Skip first routine (no FPU -> no FPU)
  329.  
  330.             base = find_rsrc_data(p, size - base - 2, dat3, sizeof(dat3), base + 2);
  331.             if (base) {    // no FPU -> FPU
  332.  
  333.                 p16 = (uint16 *)(p + base);
  334.                 start = (uint32)q;
  335.                 for (i=0; i<48; i++) *q++ = *p16++;
  336.                 *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state or "FPU state saved" flag set?)
  337.                 *q++ = htons(2);
  338.                 *q++ = htons(0x6712);        // beq
  339.                 *q++ = htons(0x588f);        // addq.l #2,sp                (flag set, skip it)
  340.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpcr        (restore FPU registers)
  341.                 *q++ = htons(0x9000);
  342.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpsr
  343.                 *q++ = htons(0x8800);
  344.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpiar
  345.                 *q++ = htons(0x8400);
  346.                 *q++ = htons(0xf21f);        // fmovem.x (sp)+,fp0-fp7
  347.                 *q++ = htons(0xd0ff);
  348.                 p16 += 7;
  349.                 for (i=0; i<20; i++) *q++ = *p16++;
  350.  
  351.                 p16 = (uint16 *)(p + base);
  352.                 *p16++ = htons(M68K_JMP);
  353.                 *p16++ = htons(start >> 16);
  354.                 *p16 = htons(start & 0xffff);
  355.                 FlushCodeCache(p + base, 6);
  356.                 D(bug("  patch 4 applied\n"));
  357.  
  358.                 static const uint8 dat4[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x50};
  359.                 base = find_rsrc_data(p, size, dat4, sizeof(dat4));
  360.                 if (base) {    // FPU -> FPU
  361.  
  362.                     p16 = (uint16 *)(p + base);
  363.                     start = (uint32)q;
  364.                     for (i=0; i<4; i++) *q++ = *p16++;
  365.                     *q++ = htons(0x675e);        // beq
  366.                     p16++;
  367.                     for (i=0; i<21; i++) *q++ = *p16++;
  368.                     *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state?)
  369.                     *q++ = htons(2);
  370.                     *q++ = htons(0x6716);        // beq
  371.                     *q++ = htons(0xf227);        // fmovem.x fp0-fp7,-(sp)    (no, save FPU registers)
  372.                     *q++ = htons(0xe0ff);
  373.                     *q++ = htons(0xf227);        // fmove.l fpiar,-(sp)
  374.                     *q++ = htons(0xa400);
  375.                     *q++ = htons(0xf227);        // fmove.l fpsr,-(sp)
  376.                     *q++ = htons(0xa800);
  377.                     *q++ = htons(0xf227);        // fmove.l fpcr,-(sp)
  378.                     *q++ = htons(0xb000);
  379.                     *q++ = htons(0x4879);        // pea -1                    (push "FPU state saved" flag)
  380.                     *q++ = htons(0xffff);
  381.                     *q++ = htons(0xffff);
  382.                     p16 += 7;
  383.                     for (i=0; i<23; i++) *q++ = *p16++;
  384.                     *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state or "FPU state saved" flag set?)
  385.                     *q++ = htons(2);
  386.                     *q++ = htons(0x6712);        // beq
  387.                     *q++ = htons(0x588f);        // addq.l #2,sp                (flag set, skip it)
  388.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpcr        (restore FPU registers)
  389.                     *q++ = htons(0x9000);
  390.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpsr
  391.                     *q++ = htons(0x8800);
  392.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpiar
  393.                     *q++ = htons(0x8400);
  394.                     *q++ = htons(0xf21f);        // fmovem.x (sp)+,fp0-fp7
  395.                     *q++ = htons(0xd0ff);
  396.                     p16 += 7;
  397.                     for (i=0; i<20; i++) *q++ = *p16++;
  398.  
  399.                     p16 = (uint16 *)(p + base);
  400.                     *p16++ = htons(M68K_JMP);
  401.                     *p16++ = htons(start >> 16);
  402.                     *p16 = htons(start & 0xffff);
  403.                     FlushCodeCache(p + base, 6);
  404.                     D(bug("  patch 5 applied\n"));
  405.  
  406.                     base = find_rsrc_data(p, size - base - 2, dat4, sizeof(dat4), base + 2);
  407.                     if (base) {    // FPU -> no FPU
  408.  
  409.                         p16 = (uint16 *)(p + base);
  410.                         start = (uint32)q;
  411.                         for (i=0; i<4; i++) *q++ = *p16++;
  412.                         *q++ = htons(0x675e);        // beq
  413.                         p16++;
  414.                         for (i=0; i<21; i++) *q++ = *p16++;
  415.                         *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state?)
  416.                         *q++ = htons(2);
  417.                         *q++ = htons(0x6716);        // beq
  418.                         *q++ = htons(0xf227);        // fmovem.x fp0-fp7,-(sp)    (no, save FPU registers)
  419.                         *q++ = htons(0xe0ff);
  420.                         *q++ = htons(0xf227);        // fmove.l fpiar,-(sp)
  421.                         *q++ = htons(0xa400);
  422.                         *q++ = htons(0xf227);        // fmove.l fpsr,-(sp)
  423.                         *q++ = htons(0xa800);
  424.                         *q++ = htons(0xf227);        // fmove.l fpcr,-(sp)
  425.                         *q++ = htons(0xb000);
  426.                         *q++ = htons(0x4879);        // pea -1                    (push "FPU state saved" flag)
  427.                         *q++ = htons(0xffff);
  428.                         *q++ = htons(0xffff);
  429.                         p16 += 7;
  430.                         for (i=0; i<42; i++) *q++ = *p16++;
  431.  
  432.                         p16 = (uint16 *)(p + base);
  433.                         *p16++ = htons(M68K_JMP);
  434.                         *p16++ = htons(start >> 16);
  435.                         *p16 = htons(start & 0xffff);
  436.                         FlushCodeCache(p + base, 6);
  437.                         D(bug("  patch 6 applied\n"));
  438.                     }
  439.                 }
  440.             }
  441.         }
  442.  
  443.         FlushCodeCache(ThPatchSpace, 1024);
  444.  
  445.         // Patch Thread Manager FPU init for 68060 FPU (7.5, 8.0)
  446.         static const uint8 dat5[] = {0x4a, 0x28, 0x00, 0xa4, 0x67, 0x0a, 0x4a, 0x2c, 0x00, 0x40};
  447.         base = find_rsrc_data(p, size, dat5, sizeof(dat5));
  448.         if (base) {
  449.             p16 = (uint16 *)(p + base + 6);
  450.             *p16++ = htons(M68K_JSR);
  451.             *p16++ = htons((uint32)ThInitFPUPatch >> 16);
  452.             *p16++ = htons((uint32)ThInitFPUPatch & 0xffff);
  453.             *p16++ = htons(M68K_NOP);
  454.             *p16 = htons(M68K_NOP);
  455.             FlushCodeCache(p + base + 6, 10);
  456.             D(bug("  patch 7 applied\n"));
  457.         }
  458. #endif
  459.  
  460.     } else if (type == FOURCC('g','p','c','h') && id == 750) {
  461.         D(bug(" gpch 750 found\n"));
  462.  
  463.         // Don't use PTEST instruction in BlockMove() (7.5, 7.6, 7.6.1, 8.0)
  464.         static const uint8 dat[] = {0x20, 0x5f, 0x22, 0x5f, 0x0c, 0x38, 0x00, 0x04, 0x01, 0x2f};
  465.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  466.         if (base) {
  467.             p16 = (uint16 *)(p + base + 4);
  468.             *p16++ = htons(M68K_EMUL_OP_BLOCK_MOVE);
  469.             *p16++ = htons(0x7000);
  470.             *p16 = htons(M68K_RTS);
  471.             FlushCodeCache(p + base + 4, 6);
  472.             D(bug("  patch 1 applied\n"));
  473.         }
  474.  
  475.     } else if (type == FOURCC('l','p','c','h') && id == 24) {
  476.         D(bug(" lpch 24 found\n"));
  477.  
  478.         // Don't replace Time Manager (7.0.1, 7.1, 7.5, 7.6, 7.6.1, 8.0)
  479.         static const uint8 dat[] = {0x70, 0x59, 0xa2, 0x47};
  480.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  481.         if (base) {
  482.             p16 = (uint16 *)(p + base + 2);
  483.             *p16++ = htons(M68K_NOP);
  484.             p16 += 3;
  485.             *p16++ = htons(M68K_NOP);
  486.             p16 += 7;
  487.             *p16 = htons(M68K_NOP);
  488.             FlushCodeCache(p + base + 2, 28);
  489.             D(bug("  patch 1 applied\n"));
  490.         }
  491.  
  492.     } else if (type == FOURCC('l','p','c','h') && id == 31) {
  493.         D(bug(" lpch 31 found\n"));
  494.  
  495.         // Don't write to VIA in vSoundDead() (7.0.1, 7.1, 7.5, 7.6, 7.6.1, 8.0)
  496.         static const uint8 dat[] = {0x20, 0x78, 0x01, 0xd4, 0x08, 0xd0, 0x00, 0x07, 0x4e, 0x75};
  497.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  498.         if (base) {
  499.             p16 = (uint16 *)(p + base);
  500.             *p16 = htons(M68K_RTS);
  501.             FlushCodeCache(p + base, 2);
  502.             D(bug("  patch 1 applied\n"));
  503.         }
  504.  
  505.         // Don't replace SCSI manager (7.1, 7.5, 7.6.1, 8.0)
  506.         static const uint8 dat2[] = {0x0c, 0x6f, 0x00, 0x0e, 0x00, 0x04, 0x66, 0x0c};
  507.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  508.         if (base) {
  509.             p16 = (uint16 *)(p + base);
  510.             *p16++ = htons(M68K_EMUL_OP_SCSI_DISPATCH);
  511.             *p16++ = htons(0x2e49);        // move.l    a1,a7
  512.             *p16 = htons(M68K_JMP_A0);
  513.             FlushCodeCache(p + base, 6);
  514.             D(bug("  patch 2 applied\n"));
  515.         }
  516.  
  517. #if !EMULATED_68K
  518.     } else if (CPUIs68060 && type == FOURCC('s','c','o','d') && (id == -16463 || id == -16464)) {
  519.         D(bug(" scod -16463/-16464 found\n"));
  520.  
  521.         // Correct 68060 FP frame handling in Process Manager task switches (7.1, 7.5, 8.0)
  522.         static const uint8 dat[] = {0xf3, 0x27, 0x4a, 0x17};
  523.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  524.         if (base) {
  525.             p16 = (uint16 *)(p + base);
  526.             *p16++ = htons(M68K_JMP);
  527.             *p16++ = htons((uint32)Scod060Patch1 >> 16);
  528.             *p16 = htons((uint32)Scod060Patch1 & 0xffff);
  529.             FlushCodeCache(p + base, 6);
  530.             D(bug("  patch 1 applied\n"));
  531.         }
  532.  
  533.         // Even a null FP frame is 3 longwords on the 68060 (7.1, 7.5, 8.0)
  534.         static const uint8 dat2[] = {0xf3, 0x5f, 0x4e, 0x75};
  535.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  536.         if (base) {
  537.             p16 = (uint16 *)(p + base - 2);
  538.             *p16++ = htons(M68K_JMP);
  539.             *p16++ = htons((uint32)Scod060Patch2 >> 16);
  540.             *p16 = htons((uint32)Scod060Patch2 & 0xffff);
  541.             FlushCodeCache(p + base - 2, 6);
  542.             D(bug("  patch 2 applied\n"));
  543.         }
  544. #endif
  545.  
  546.     } else if (type == FOURCC('t','h','n','g') && id == -16563) {
  547.         D(bug(" thng -16563 found\n"));
  548.  
  549.         // Set audio component flags (7.5, 7.6, 7.6.1, 8.0)
  550.         *(uint32 *)(p + componentFlags) = htonl(audio_component_flags);
  551.         D(bug("  patch 1 applied\n"));
  552.  
  553.     } else if (type == FOURCC('s','i','f','t') && id == -16563) {
  554.         D(bug(" sift -16563 found\n"));
  555.  
  556.         // Replace audio component (7.5, 7.6, 7.6.1, 8.0)
  557.         p16 = (uint16 *)p;
  558.         *p16++ = htons(0x4e56); *p16++ = htons(0x0000);    // link        a6,#0
  559.         *p16++ = htons(0x48e7); *p16++ = htons(0x8018);    // movem.l    d0/a3-a4,-(sp)
  560.         *p16++ = htons(0x266e); *p16++ = htons(0x000c);    // movea.l    12(a6),a3
  561.         *p16++ = htons(0x286e); *p16++ = htons(0x0008);    // movea.l    8(a6),a4
  562.         *p16++ = htons(M68K_EMUL_OP_AUDIO);
  563.         *p16++ = htons(0x2d40); *p16++ = htons(0x0010);    // move.l    d0,16(a6)
  564.         *p16++ = htons(0x4cdf); *p16++ = htons(0x1801);    // movem.l    (sp)+,d0/a3-a4
  565.         *p16++ = htons(0x4e5e);                            // unlk        a6
  566.         *p16++ = htons(0x4e74); *p16++ = htons(0x0008);    // rtd        #8
  567.         FlushCodeCache(p, 32);
  568.         D(bug("  patch 1 applied\n"));
  569.  
  570.     } else if (type == FOURCC('i','n','s','t') && id == -19069) {
  571.         D(bug(" inst -19069 found\n"));
  572.  
  573.         // Don't replace Microseconds (QuickTime 2.0)
  574.         static const uint8 dat[] = {0x30, 0x3c, 0xa1, 0x93, 0xa2, 0x47};
  575.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  576.         if (base) {
  577.             p16 = (uint16 *)(p + base + 4);
  578.             *p16 = htons(M68K_NOP);
  579.             FlushCodeCache(p + base + 4, 2);
  580.             D(bug("  patch 1 applied\n"));
  581.         }
  582.  
  583.     } else if (type == FOURCC('D','R','V','R') && id == -20066) {
  584.         D(bug("DRVR -20066 found\n"));
  585.  
  586.         // Don't access SCC in .Infra driver
  587.         static const uint8 dat[] = {0x28, 0x78, 0x01, 0xd8, 0x48, 0xc7, 0x20, 0x0c, 0xd0, 0x87, 0x20, 0x40, 0x1c, 0x10};
  588.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  589.         if (base) {
  590.             p16 = (uint16 *)(p + base + 12);
  591.             *p16 = htons(0x7a00);    // moveq #0,d6
  592.             FlushCodeCache(p + base + 12, 2);
  593.             D(bug("  patch 1 applied\n"));
  594.         }
  595.  
  596.     } else if (type == FOURCC('l','t','l','k') && id == 0) {
  597.         D(bug(" ltlk 0 found\n"));
  598.  
  599.         // Disable LocalTalk (7.0.1, 7.5, 7.6, 7.6.1, 8.0)
  600.         p16 = (uint16 *)p;
  601.         *p16++ = htons(M68K_JMP_A0);
  602.         *p16++ = htons(0x7000);
  603.         *p16 = htons(M68K_RTS);
  604.         FlushCodeCache(p, 6);
  605.         D(bug("  patch 1 applied\n"));
  606.     }
  607. #if REAL_ADDRESSING && !defined(AMIGA)
  608.     else if (type == FOURCC('D','R','V','R') && id == 41) {
  609.         D(bug(" DRVR 41 found\n"));
  610.         
  611.         // gb-- [0x28E (ROM85)] contains 0x3fff that will be placed into a0
  612.         // Seems to be caused by the AppleShare extension from MacOS 8.1 (3.7.4)
  613.         // .AFPTranslator (DRVR addr 0x2372)
  614.         static const uint8 dat[] = {0x3a, 0x2e, 0x00, 0x0a, 0x55, 0x4f, 0x3e, 0xb8, 0x02, 0x8e, 0x30, 0x1f, 0x48, 0xc0, 0x24, 0x40, 0x20, 0x40};
  615.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  616.         if (base) {
  617.             p16 = (uint16 *)(p + base + 4);
  618.             *p16++ = htons(0x3078);        // movea.w    ROM85,%a0
  619.             *p16++ = htons(0x028e);
  620.             *p16++ = htons(0xd1fc);        // adda.l    #RAMBaseMac,%a0
  621.             *p16++ = htons((RAMBaseMac >> 16) & 0xffff);
  622.             *p16++ = htons(RAMBaseMac & 0xffff);
  623.             *p16++ = htons(0x2448);        // movea.l    %a0,%a2
  624.             *p16++ = htons(M68K_NOP);
  625.             FlushCodeCache(p + base + 4, 14);
  626.             D(bug("  patch 1 applied\n"));
  627.         }
  628.     }
  629. #endif
  630. }
  631.